﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Caching;
using NLog;

namespace Gollie.WebCache
{
    public abstract class CacheDependencyBase : ICacheable
    {
		protected static Logger logger = LogManager.GetCurrentClassLogger();

        public CacheDependencyBase()
			: this((string[])null)
        {
        }

		public CacheDependencyBase(string[] dependsOn)
		{
			Policy = CreatePolicy(dependsOn);
		}

		public CacheDependencyBase(string path)
			: this(path, null)
		{
		}

		public CacheDependencyBase(string path, string[] dependsOn)
		{
			Policy = CreatePolicy(path, dependsOn);
		}

		public CacheDependencyBase(int expirationPeriod)
			: this(expirationPeriod, null)
		{
		}

		public CacheDependencyBase(int expirationPeriod, string[] dependsOn)
		{
			Policy = CreatePolicy(expirationPeriod, dependsOn);
		}

		public static CacheItemPolicy CreatePolicy(string path)
		{
			var policy = new CacheItemPolicy();

			policy.ChangeMonitors.Add(new HostFileChangeMonitor(new string[] { path }));

			return policy;
		}

		public static CacheItemPolicy CreatePolicy(string path, string[] dependsOn)
		{
			var policy = CreatePolicy(path);

			AddDependencies(policy, dependsOn);

			return policy;
		}

		public static CacheItemPolicy CreatePolicy(int expirationPeriod)
		{
			return new CacheItemPolicy() { AbsoluteExpiration = DateTime.Now.AddSeconds(expirationPeriod) };
		}

		public static CacheItemPolicy CreatePolicy(int expirationPeriod, string[] dependsOn)
		{
			var policy = CreatePolicy(expirationPeriod);

			AddDependencies(policy, dependsOn);

			return policy;
		}

		public static CacheItemPolicy CreatePolicy(string[] dependsOn)
		{
			var policy = new CacheItemPolicy();

			AddDependencies(policy, dependsOn);

			return policy;
		}

		private static void AddDependencies(CacheItemPolicy policy, string[] dependsOn)
		{
			if (dependsOn != null && dependsOn.Length > 0)
				policy.ChangeMonitors.Add(DataCache.Cache.CreateCacheEntryChangeMonitor(dependsOn));
		}

        #region ICacheable

		public CacheItemPolicy Policy { get; set; }
		public virtual void Initialize(params object[] args)
		{ }

        #endregion
    }
}